//
//  NXSignatureView.m
//  EsayHandwritingSignature
//
//  Created by N-X on 2017/11/24.
//  Copyright © 2017年 liang. All rights reserved.
//

#import "NXSignatureView.h"

static CGPoint midpoint(CGPoint p0,CGPoint p1) {
    //    return (CGPoint) {
    //        (p0.x + p1.x) /2.0,
    //        (p0.y + p1.y) /2.0
    //    };
    CGPoint point = {
        (p0.x + p1.x) /2.0,
        (p0.y + p1.y) /2.0
    };
    return point;
}

@interface NXSignatureView()

@property (nonatomic ,strong)CAShapeLayer * shapLayer;
@property (nonatomic ,strong)UIBezierPath * bezierPath;
@property (nonatomic ,strong)NSMutableArray * layerArray;
@property(nonatomic,assign)CGFloat minX;
@property(nonatomic,assign)CGFloat minY;
@property(nonatomic,assign)CGFloat maxX;
@property(nonatomic,assign)CGFloat maxY;

@end

@implementation NXSignatureView

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit
{
    _minX = 0;
    _minY = 0;
    _maxX = 0;
    _maxY = 0;
}

#pragma mark - setter && getter

- (UIBezierPath *)bezierPath
{
    if (!_bezierPath) {
        _bezierPath = [UIBezierPath bezierPath];
        _bezierPath.lineCapStyle = kCGLineCapRound;
        _bezierPath.lineJoinStyle = kCGLineJoinRound;
    }
    return _bezierPath;
}

- (NSMutableArray *)layerArray
{
    if (!_layerArray) {
        _layerArray = [NSMutableArray array];
    }
    return _layerArray;
}

#pragma mark - 触摸事件

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (self.delegate != nil &&[self.delegate respondsToSelector:@selector(onSignatureWriteAction)]) {
        [self.delegate onSignatureWriteAction];
    }
    CGPoint startPoint = [self pointWithTouches:touches];
    [self setMixMinYMaxXMaxYWithTouched:touches];
    [self.bezierPath moveToPoint:startPoint];
    [self drawStartPoint:startPoint];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CGPoint currentPoint = [self pointWithTouches:touches];
    [self setMixMinYMaxXMaxYWithTouched:touches];
    [self.bezierPath addLineToPoint:currentPoint];
    self.shapLayer.path = self.bezierPath.CGPath;
}

- (CGPoint)pointWithTouches:(NSSet<UITouch *>*)touches
{
    UITouch * touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    CGPoint newPoint = CGPointMake(point.x - self.frame.origin.x, point.y - self.frame.origin.y);
    NSLog(@"point:%@",NSStringFromCGPoint(point));
    return newPoint;
}

- (void)drawStartPoint:(CGPoint)point
{
    _shapLayer = [CAShapeLayer layer];
    _shapLayer.lineWidth = 2.5;
    //    _shapLayer.path = self.bezierPath.CGPath;
    _shapLayer.frame = self.frame;
    _shapLayer.lineCap =  kCALineCapRound;
    _shapLayer.lineJoin = kCALineJoinRound;
    _shapLayer.strokeColor = [UIColor blackColor].CGColor;
    _shapLayer.fillColor = [UIColor clearColor].CGColor;
    [self.layer addSublayer:self.shapLayer];
    self.clipsToBounds = YES;
    [self.layerArray addObject:self.shapLayer];
}

- (void)setMixMinYMaxXMaxYWithTouched:(NSSet<UITouch *>*)touches
{
    UITouch * touch = [touches anyObject];
    CGPoint currentPoint = [touch locationInView:self];
    
    CGFloat viewHeight = self.frame.size.height;
    CGFloat currentY = currentPoint.y;
    
    if(0 <= currentY && currentY <= viewHeight)
    {
        if(_maxX == 0 && _minX == 0)
        {
            _maxX = currentPoint.x;
            _minX = currentPoint.x;
            _maxY = currentPoint.y;
            _minY = currentPoint.y;
        }
        else
        {
            if(_maxX <= currentPoint.x)
            {
                _maxX = currentPoint.x;
            }
            if (_maxY <= currentPoint.y) {
                
                _maxY = currentPoint.y;
            }
            if (_minY >= currentPoint.y) {
                
                _minY = currentPoint.y;
            }
            if(_minX>=currentPoint.x)
            {
                _minX = currentPoint.x;
            }
        }
    }
}

- (void) imageRepresentation
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size,NO, [UIScreen mainScreen].scale);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    image = [self imageToTransparent:image];
    
    NSLog(@"width:%f,height:%f",image.size.width,image.size.height);
    
    UIImage *img = [self cutImage:image];
    self.SignatureImg = [self scaleToSize:img];
}

//压缩图片,最长边为60(根据不同的比例来压缩)
- (UIImage *)scaleToSize:(UIImage *)img {
    CGRect rect ;
    CGFloat imageWidth = img.size.width;
    //判断图片宽度
    //    if(imageWidth >= 60)
    //    {
    //        rect =CGRectMake(0,0, 60, 60 * img.size.height / imageWidth);
    //    }
    //    else
    //    {
    //        rect =CGRectMake(0,0, img.size.width,img.size.height);
    //
    //    }
    rect = CGRectMake(0, 0, 400, 150);
    CGSize size = rect.size;
    //    UIGraphicsBeginImageContext(size);
    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
    [img drawInRect:rect];
    UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    //此处注释是为了防止该签名图片被保存到本地
    //    UIImageWriteToSavedPhotosAlbum(scaledImage,nil, nil, nil);
    return scaledImage;
}

//只截取签名部分图片
- (UIImage *)cutImage:(UIImage *)image
{
    CGRect rect ;
    CGFloat scale = [UIScreen mainScreen].scale;
    //签名事件没有发生
    if(_minX == 0 && _maxX == 0)
    {
        rect =CGRectMake(0,0, 0, 0);
    }
    else//签名发生
    {
        rect =CGRectMake(_minX -3 < 0 ? 0 : (_minX - 3), _minY - 3 < 0 ? 0 : (_minY - 3), (_maxX- _minX+ 6),(_maxY - _minY + 6));
    }
    CGImageRef imageRef =CGImageCreateWithImageInRect([image CGImage], rect);
    UIImage * img = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return img;
}

void ProviderReleaseData (void *info,const void *data,size_t size)
{
    free((void*)data);
}

//颜色替换
- (UIImage*) imageToTransparent:(UIImage*) image
{
    // 分配内存
    const int imageWidth = image.size.width;
    const int imageHeight = image.size.height;
    size_t      bytesPerRow = imageWidth * 4;
    uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
    
    // 创建context
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
    
    // 遍历像素
    int pixelNum = imageWidth * imageHeight;
    uint32_t* pCurPtr = rgbImageBuf;
    for (int i = 0; i < pixelNum; i++, pCurPtr++)
    {
        
        //把绿色变成黑色，把背景色变成透明
        if ((*pCurPtr & 0x65815A00) == 0x65815a00)    // 将背景变成透明
        {
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[0] = 0;
        }
        else if ((*pCurPtr & 0x00FF0000) == 0x00ff0000)    // 将绿色变成黑色
        {
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[3] = 0; //0~255
            ptr[2] = 0;
            ptr[1] = 0;
        }
        else if ((*pCurPtr & 0xFFFFFF00) == 0xffffff00)    // 将白色变成透明
        {
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[0] = 0;
        }
        else
        {
            // 改成下面的代码，会将图片转成想要的颜色
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[3] = 0; //0~255
            ptr[2] = 0;
            ptr[1] = 0;
        }
        
    }
    
    // 将内存转成image
    CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace,
                                        kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
                                        NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease(dataProvider);
    
    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
    
    // 释放
    CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    // free(rgbImageBuf) 创建dataProvider时已提供释放函数，这里不用free
    
    return resultUIImage;
}

#pragma mark - 按钮点击事件处理

- (void)sure
{
    return [self imageRepresentation];
}

- (void)clear
{
    if (!_layerArray.count) {
        return;
    }
    [self.layerArray makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
    [self.bezierPath removeAllPoints];
    [self.layerArray removeAllObjects];
}

@end
